home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / sun4c.md / devSCSIC90Mach.c < prev    next >
C/C++ Source or Header  |  1991-08-02  |  10KB  |  375 lines

  1.  /* 
  2.  * devSCSIC90Mach.c --
  3.  *
  4.  *    Routines specific to the SCSI NCR 53C9X Host Adaptor which
  5.  *    depend on the machine architecture.
  6.  *
  7.  * Copyright 1991 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/kernel/dev/sun4c.md/RCS/devSCSIC90Mach.c,v 1.1 91/08/01 21:02:28 mottsmth Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include "sprite.h"
  22. #include "devAddrs.h"
  23. #include "scsiC90.h"
  24. #include "mach.h"
  25. #include "dev.h"
  26. #include "devInt.h"
  27. #include "scsiHBA.h"
  28. #include "scsiDevice.h"
  29. #include "sync.h"
  30. #include "stdio.h"
  31. #include "stdlib.h"
  32. #include "string.h"
  33. #include "devSCSIC90.h"
  34. #include "devSCSIC90Int.h"
  35.  
  36. extern Boolean DevEntryAvailProc();
  37. /*
  38.  * Forward declarations.  
  39.  */
  40.  
  41. static Boolean          ProbeOnBoard _ARGS_ ((int address));
  42. static Boolean          ProbeSBus _ARGS_ ((int address));
  43.  
  44. /*
  45.  * This already seems to be mapped at this virtual address.  Should I remap it?
  46.  */
  47. volatile DMARegs    *dmaRegsPtr = (volatile DMARegs *) 0xffd14000;
  48. int    dmaControllerActive = 0;
  49.  
  50.  
  51. /*
  52.  *----------------------------------------------------------------------
  53.  *
  54.  * ProbeOnBoard --
  55.  *
  56.  *    Test for the existence for the interface.
  57.  *
  58.  * Results:
  59.  *    TRUE if the host adaptor was found.
  60.  *
  61.  * Side effects:
  62.  *    None.
  63.  *
  64.  *----------------------------------------------------------------------
  65.  */
  66. static Boolean
  67. ProbeOnBoard(address)
  68.     int address;            /* Alledged controller address */
  69. {
  70.     ReturnStatus    status;
  71.     volatile CtrlRegs    *regsPtr = (volatile CtrlRegs *) address;
  72.     int            x;
  73.  
  74.     /*
  75.      * Touch the device's status register.  Should I read something else?
  76.      */
  77.     status = Mach_Probe(sizeof (regsPtr->scsi_ctrl.read.status),
  78.         (Address) &(regsPtr->scsi_ctrl.read.status), (Address) &x);
  79.     if (status != SUCCESS) {
  80.     if (devSCSIC90Debug > 3) {
  81.         printf("Onboard SCSIC90 not found at address 0x%x\n",address);
  82.     }
  83.         return (FALSE);
  84.     }
  85.     if (devSCSIC90Debug > 3) {
  86.     printf("Onboard SCSIC90 found\n");
  87.     }
  88.     return(TRUE);
  89. }
  90.  
  91. /*
  92.  *----------------------------------------------------------------------
  93.  *
  94.  * ProbeSBus --
  95.  *
  96.  *    Probe memory for a host adaptor on the sbus.
  97.  *
  98.  * Results:
  99.  *    TRUE if the host adaptor was found, but right now we only handle
  100.  *    the on-board scsi controller.
  101.  *
  102.  * Side effects:
  103.  *    None.
  104.  *
  105.  *----------------------------------------------------------------------
  106.  */
  107. static Boolean
  108. ProbeSBus(address)
  109.     int address;            /* Alledged controller address */
  110. {
  111.     /* We don't do this yet. */
  112.     return (FALSE);
  113. }
  114.  
  115.  
  116. /*
  117.  *----------------------------------------------------------------------
  118.  *
  119.  * DevReset --
  120.  *
  121.  *    Reset a SCSI bus controlled by the SCSI-3 Sun Host Adaptor.
  122.  *
  123.  * Results:
  124.  *    None.
  125.  *
  126.  * Side effects:
  127.  *    Reset the controller and SCSI bus.
  128.  *
  129.  *----------------------------------------------------------------------
  130.  */
  131. void
  132. DevReset(ctrlPtr)
  133.     Controller *ctrlPtr;
  134. {
  135.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  136.     Device *devPtr;
  137.     int i,j;
  138.  
  139.     /* Reset scsi controller. */
  140.     regsPtr->scsi_ctrl.write.command = CR_RESET_CHIP;
  141.     MACH_DELAY(200);
  142.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_NOP;
  143.     MACH_DELAY(200);
  144.     dmaControllerActive = 0;        /* Allow dma reset to happen. */
  145.     Dev_ScsiResetDMA();
  146.     MACH_DELAY(200);
  147.  
  148.     regsPtr->scsi_ctrl.write.config1 |= C1_REPORT;
  149.     MACH_DELAY(200);
  150.     regsPtr->scsi_ctrl.write.command = CR_RESET_BUS;
  151.     MACH_DELAY(800);
  152.     for (i=0; i<8; i++) {
  153.     for (j=0; j<8; j++) {
  154.         devPtr = ctrlPtr->devicePtr[i][j];
  155.         if ((devPtr != (Device *)NIL) && (devPtr != (Device *)0)) {
  156.         devPtr->synchPeriod = 0;
  157.         devPtr->synchOffset = 0;
  158.         }
  159.     }
  160.     }
  161.     /*
  162.      * We initialize configuration, clock conv, synch offset, etc, in
  163.      * SendCommand.
  164.      * Parity is disabled by hardware reset or software.
  165.      */
  166.  
  167.     return;
  168. }
  169.  
  170.  
  171. /*
  172.  *----------------------------------------------------------------------
  173.  *
  174.  * Dev_ScsiResetDMA --
  175.  *
  176.  *    Reset the DMA controller.  The SCSI module owns the dma controller,
  177.  *    so it gets to decide when it may be reset or not.  The network
  178.  *    module also calls us to try to reset it.
  179.  *
  180.  * Results:
  181.  *    None.
  182.  *
  183.  * Side effects:
  184.  *    DMA chip reset.
  185.  *
  186.  *----------------------------------------------------------------------
  187.  */
  188. void
  189. Dev_ScsiResetDMA()
  190. {
  191.     static    int    whichTime = 0;
  192.  
  193.     if (whichTime > 1) {
  194.     return;
  195.     }
  196.  
  197.     whichTime++;
  198.  
  199.     if (dmaControllerActive > 0 && devSCSIC90Debug > 4) {
  200.     printf("Wanted to reset dma controller, but it was active: %d\n",
  201.         dmaControllerActive);
  202.     return;
  203.     }
  204.  
  205.     /* Reset dma controller. */
  206.     dmaRegsPtr->ctrl = DMA_RESET;
  207.     MACH_DELAY(200);
  208.     /* Reset the dma reset bit. */
  209.     dmaRegsPtr->ctrl = dmaRegsPtr->ctrl & ~(DMA_RESET);
  210.     /* Allow dma interrupts. */
  211.     dmaRegsPtr->ctrl = DMA_INT_EN;
  212.     MACH_DELAY(200);
  213.  
  214.     if (devSCSIC90Debug > 4) {
  215.     printf("Returning from Reset command.\n");
  216.     }
  217.  
  218.     return;
  219. }
  220.  
  221.  
  222. /*
  223.  *----------------------------------------------------------------------
  224.  *
  225.  * DevStartDMA --
  226.  *
  227.  *    Issue the sequence of commands to the controller to start DMA.
  228.  *    This can be called by Dev_SCSIC90Intr in response to a DATA_{IN,OUT}
  229.  *    phase message.
  230.  *
  231.  * Results:
  232.  *    None.
  233.  *
  234.  * Side effects:
  235.  *    DMA is enabled.  No registers other than the control register are
  236.  *    to be accessed until DMA is disabled again.
  237.  *
  238.  *----------------------------------------------------------------------
  239.  */
  240. void
  241. DevStartDMA(ctrlPtr)
  242.     Controller *ctrlPtr;
  243. {
  244.     volatile CtrlRegs    *regsPtr;
  245.     int            size;
  246.     Device              *devPtr = ctrlPtr->devPtr;
  247.     Address             buffer;
  248.  
  249.     size = devPtr->activeBufLen;
  250.     buffer = devPtr->activeBufPtr;
  251.  
  252.     if (devSCSIC90Debug > 4) {
  253.     printf("StartDMA called for %s, dma %s, size = %d.\n", ctrlPtr->name,
  254.         (devPtr->dmaState == DMA_RECEIVE) ? "receive" :
  255.         ((devPtr->dmaState == DMA_SEND) ? "send" :
  256.                           "not-active!"), size);
  257.     }
  258.     if (devPtr->dmaState == DMA_INACTIVE) {
  259.     printf("StartDMA: Returning, since DMA state isn't active.\n");
  260.     return;
  261.     }
  262.     regsPtr = ctrlPtr->regsPtr;
  263.     /*
  264.      * A DMA cannot cross a 16Mbyte boundary using this dma controller.
  265.      * We could remap pages if it does, but since the file system won't
  266.      * do this, we just panic for now.
  267.      */
  268.     if (((unsigned) buffer & 0xff000000) !=
  269.         (((unsigned) buffer + size - 1) & 0xff000000)) {
  270.     panic("DMA crosses 16Mbyte boundary.\n");
  271.     }
  272.     if (buffer == (Address) NIL) {
  273.     panic("DMA buffer was NIL before dma.\n");
  274.     }
  275.     dmaRegsPtr->addr = (unsigned int) buffer;
  276.  
  277.     /*
  278.      * Put transfer size in counter.  If this is 16k (max size), this puts
  279.      * a 0 in the counter, which is the correct thing to do.
  280.      */
  281.     /* High byte of size. */
  282.     regsPtr->scsi_ctrl.write.xCntHi = (unsigned char) ((size & 0xff00) >> 8);
  283.     /* Low byte of size. */
  284.     regsPtr->scsi_ctrl.write.xCntLo = (unsigned char) (size & 0x00ff);
  285.     /* Load count into counter by writing a DMA NOP command on C90 only */
  286.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_NOP;
  287.     /* Enable DMA */
  288.     if (devPtr->dmaState == DMA_RECEIVE) {
  289.     dmaRegsPtr->ctrl = DMA_EN_DMA | DMA_READ | DMA_INT_EN;
  290.     } else {
  291.     dmaRegsPtr->ctrl = DMA_EN_DMA | DMA_INT_EN;
  292.     }
  293.     /* Start scsi command. */
  294.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_XFER_INFO;
  295.  
  296.     return;
  297. }
  298.  
  299.  
  300. /*
  301.  *----------------------------------------------------------------------
  302.  *
  303.  * DevSCSIC90Init --
  304.  *
  305.  *    Check for the existant of the Sun SCSIC90 HBA controller. If it
  306.  *    exists allocate data stuctures for it.
  307.  *
  308.  * Results:
  309.  *    TRUE if the controller exists, FALSE otherwise.
  310.  *
  311.  * Side effects:
  312.  *    Memory may be allocated.
  313.  *
  314.  *----------------------------------------------------------------------
  315.  */
  316. ClientData
  317. DevSCSIC90Init(ctrlLocPtr)
  318.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  319. {
  320.     int    ctrlNum;
  321.     Boolean    found;
  322.     Controller *ctrlPtr;
  323.     int    i,j;
  324.     static int numSCSIC90Controllers = 0; /* highest controller we've
  325.                        * probed for */
  326.  
  327.     /*
  328.      * See if the controller is there. 
  329.      */
  330.     ctrlNum = ctrlLocPtr->controllerID;
  331.     found =  (ctrlLocPtr->space == DEV_SBUS_OB) ?
  332.         ProbeOnBoard(ctrlLocPtr->address) :
  333.         ProbeSBus(ctrlLocPtr->address);
  334.     if (!found) {
  335.     return DEV_NO_CONTROLLER;
  336.     }
  337.  
  338.     /*
  339.      * It's there. Allocate and fill in the Controller structure.
  340.      */
  341.     if (ctrlNum+1 > numSCSIC90Controllers) {
  342.     numSCSIC90Controllers = ctrlNum+1;
  343.     }
  344.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  345.     bzero((char *) ctrlPtr, sizeof(Controller));
  346.     ctrlPtr->regsPtr = (volatile CtrlRegs *) (ctrlLocPtr->address);
  347.     ctrlPtr->name = ctrlLocPtr->name;
  348.     Sync_SemInitDynamic(&(ctrlPtr->mutex), ctrlPtr->name);
  349.     /* 
  350.      * Initialized the name, device queue header, and the master lock.
  351.      * The controller comes up with no devices active and no devices
  352.      * attached.  Reserved the devices associated with the 
  353.      * targetID of the controller (7).
  354.      */
  355.     ctrlPtr->devPtr = (Device *)NIL;
  356.     ctrlPtr->interruptDevPtr = (Device *)NIL;
  357.     ctrlPtr->devQueuesMask = 0;
  358.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),
  359.                           DevEntryAvailProc);
  360.     for (i = 0; i < 8; i++) {
  361.     for (j = 0; j < 8; j++) {
  362.         ctrlPtr->devicePtr[i][j] =
  363.         (i == 7) ? (Device *) 0 : (Device *) NIL;
  364.     }
  365.     }
  366.     Controllers[ctrlNum] = ctrlPtr;
  367.     DevReset(ctrlPtr);
  368.  
  369.     if (devSCSIC90Debug > 3) {
  370.     printf("devSCSIC90Init: controller 0x%02x initialized.\n", ctrlNum);
  371.     }
  372.  
  373.     return (ClientData) ctrlPtr;
  374. }
  375.